﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using GRV11;
using System.Runtime.InteropServices;

using gpuimp.core;
using gpuimp.core.ColorConverter;



namespace gpuimp.ui
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        #region ColorUnderCursor Struct + DLL Imports + GetPixel Method
        private struct POINTAPI
        {
            public uint X;
            public uint Y;
        }

        [DllImport("gdi32")]
        private static extern int GetPixel(int hdc, int nXPos, int nYPos);
        [DllImport("user32")]
        private static extern int GetWindowDC(int hwnd);
        [System.Runtime.InteropServices.DllImport("user32")]
        private static extern int GetCursorPos(out POINTAPI lpPoint);
        [DllImport("user32")]
        private static extern int ReleaseDC(int hWnd, int hDC);

        private static SolidColorBrush GetPixelColor(Point point)
        {
            int lDC = GetWindowDC(0);
            int intColor = GetPixel(lDC, (int)point.X, (int)point.Y);
            //
            // Release the DC after getting the Color.
            ReleaseDC(0, lDC);

            //byte a = (byte)( ( intColor >> 0x18 ) & 0xffL );
            byte b = (byte)((intColor >> 0x10) & 0xffL);
            byte g = (byte)((intColor >> 8) & 0xffL);
            byte r = (byte)(intColor & 0xffL);
            Color color = Color.FromRgb(r, g, b);
            return new SolidColorBrush(color);
        }
        #endregion
        
        #region Global Variables
        //this is temporary (used to test) - need to create a Document/Image/etc - some kind of proprietary class eventually
        protected List<TabItem> documentsList { get; set; }
        protected int previewX;
        protected int previewY;
        protected Rectangle previewSnap = new Rectangle() { VerticalAlignment = VerticalAlignment.Top, HorizontalAlignment = HorizontalAlignment.Left, Margin = new Thickness(5, 5, 5, 5) };
        protected string documentName;
     
        private byte[] pixels;
        Tool paintbrush;
        ToolManager toolManager;
        ColorManager colorManager;

        private int numBlends;

        #endregion

        Color c1 = Colors.Green;
        Color c2 = Colors.Red;

        SelectionState selectionState;
        bool firstSelect = true;
        System.Drawing.Point firstSelectionPoint;
        bool colorPickerActive = false;

        #region Main Window
        public Window1()
        {
            InitializeComponent();
            documentsList = new List<TabItem>();

            GRControl gr = new GRControl();
            wfhCanvasHost.Child = gr;

            cbModifiers.SelectedIndex = 1;

            gr.Paint += new System.Windows.Forms.PaintEventHandler(gr_Paint);
            CanvasManager.gr = gr.GetGR();
            wfhCanvasHost.Child.MouseDown += new System.Windows.Forms.MouseEventHandler(Child_MouseClick);
            wfhCanvasHost.Child.MouseMove += new System.Windows.Forms.MouseEventHandler(Child_MouseMove);
            wfhCanvasHost.Child.MouseUp += new System.Windows.Forms.MouseEventHandler(Child_MouseUp);
            //test some stuff real quick           

            colorManager = new ColorManager();
            savedColors.ItemsSource = colorManager.getRecentColors();

            toolManager = new ToolManager();

            lbBasicColors.ItemsSource = colorManager.basicPalette();

            paintbrush = new Paintbrush();
            Tool eraser = new Eraser();
            Tool paintbucket = new Paintbucket();

            //read in default tool settings
            ConfigManager.ReadConfigFile("ToolConfig.xml");

            SolidColorBrush foreground = new SolidColorBrush(colorManager.getForeground());
            SolidColorBrush background = new SolidColorBrush(colorManager.getBackground());
            rectForegroundColor.Fill = foreground;
            rectBackgroundColor.Fill = background;

            List<int> stepList = new List<int>();
            for (int i = 1; i < 47; i++)
            {
                stepList.Add(i);
            }
            cbSteps.ItemsSource = stepList;
            cbSteps.SelectedIndex = 0;          

            numBlends = 0;

            TabbedDocuments.TabRowTabControl.ItemsSource = CanvasManager.Canvases;
            TabbedDocuments.TabRowTabControl.SelectionChanged += new SelectionChangedEventHandler(TabRowTabControl_SelectionChanged);

            selectionState = SelectionState.None;
        }

        void TabRowTabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (CanvasManager.CurrentCanvas != null)
            {
                CanvasManager.CurrentCanvasNew = TabbedDocuments.TabRowTabControl.SelectedIndex;
                lbHistory.ItemsSource = CanvasManager.getCanvas(TabbedDocuments.TabRowTabControl.SelectedIndex).StateManager.getStates;
                lbHistory.Items.Refresh();
                lbLayers.ItemsSource = CanvasManager.CurrentCanvas.LayerManager.Layers;
                lbLayers.Items.Refresh();

            }            
        }

        System.Drawing.PointF lastMousePos = new System.Drawing.Point(-1, -1);
        List<System.Drawing.PointF> pastPositions = new List<System.Drawing.PointF>();
        bool dragging = false;
        void Child_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            if (selectionState == SelectionState.Rectangle && firstSelect == false)
            {
                CanvasManager.CurrentCanvas.Selection.GenerateMesh(false, firstSelectionPoint, new System.Drawing.PointF(e.X, (float)Height - e.Y), new System.Drawing.PointF((float)wfhCanvasHost.ActualWidth, (float)wfhCanvasHost.ActualHeight));
                dragging = true;
            }
            else if (selectionState == SelectionState.Ellipse && firstSelect == false)
            {
                CanvasManager.CurrentCanvas.Selection.GenerateMesh(true, firstSelectionPoint, new System.Drawing.PointF(e.X, (float)Height - e.Y), new System.Drawing.PointF((float)wfhCanvasHost.ActualWidth, (float)wfhCanvasHost.ActualHeight));
                dragging = true;
            }
            else if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                if (ToolManager.ActiveTool != null)
                {
                    if (CanvasManager.CurrentCanvas != null)
                    {
                        System.Drawing.PointF p = new System.Drawing.Point(e.X, e.Y);
                        //p.X /= (float)500.0;
                        //p.Y /= (float)wfhCanvasHost.Height;
                        //800 because wfhCanvasHost.Width is returning NaN??
                        // if(p.X >= 0 && p.Y >= 0 && p.X < 800 && p.Y < wfhCanvasHost.Height)
                        System.Windows.Media.Color color = new Color();
                        color = colorManager.getForeground();
                        //paintbrush.draw(wfhCanvasHost.Child as GRControl, p, color);

                        if (ToolManager.ActiveTool is Eraser)
                        {
                            //color.ScA = 0;
                            //color.A = 0;

                            ToolManager.ActiveTool.draw(wfhCanvasHost.Child as GRControl, p, pastPositions, color, 1.0f);
                        }
                        else
                        {
                            ToolManager.ActiveTool.draw(wfhCanvasHost.Child as GRControl, p, pastPositions, color, 1.0f);
                        }

                        //only want to hold two points here
                        if (pastPositions.Count > 1) pastPositions.RemoveAt(0);
                        pastPositions.Add(p);
                    }
                }
                dragging = true;
            }
            else if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                System.Drawing.PointF currentPos = new System.Drawing.Point(e.X, e.Y);
                if (dragging)
                    CanvasManager.CurrentCanvas.Zoom += (float)(currentPos.X - lastMousePos.X) * 0.01f;
                lastMousePos = currentPos;
                dragging = true;
            }
            else if (e.Button == System.Windows.Forms.MouseButtons.Middle)
            {
                System.Drawing.PointF currentPos = new System.Drawing.Point(e.X, e.Y);
                if (dragging)
                {
                    System.Drawing.PointF newPos = CanvasManager.CurrentCanvas.Position;
                    newPos.X += (currentPos.X - lastMousePos.X) / CanvasManager.CurrentCanvas.Zoom;
                    newPos.Y -= (currentPos.Y - lastMousePos.Y) / CanvasManager.CurrentCanvas.Zoom;
                    CanvasManager.CurrentCanvas.Position = new System.Drawing.Point((int)newPos.X, (int)newPos.Y);
                }
                lastMousePos = currentPos;
                dragging = true;
            }
            else
            {
                lastMousePos.X = -1;
                lastMousePos.Y = -1;
            }
            wfhCanvasHost.Child.Refresh();
        }

        void Child_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            Console.WriteLine(e.X + " " + e.Y);
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                if (colorPickerActive)
                {
                    colorPickerActive = false;
                    System.Drawing.PointF point = new System.Drawing.PointF(e.X, e.Y);
                    float dW = (float)(CanvasManager.CurrentCanvas.ImageSize.X - wfhCanvasHost.ActualWidth);
                    float dH = (float)(CanvasManager.CurrentCanvas.ImageSize.Y - wfhCanvasHost.ActualHeight);
                    Point offset = new Point();
                    offset.X = (int)(dW * 0.5f);
                    //offset.X -= canvas.ImageSize.X / 2;
                    offset.X -= CanvasManager.CurrentCanvas.Position.X;
                    offset.Y = (int)(dH * 0.5f);
                    //offset.Y -= canvas.ImageSize.Y / 2;
                    offset.Y -= CanvasManager.CurrentCanvas.Position.Y;

                    point.X += (float)offset.X;
                    point.Y += (float)offset.Y;

                    //flip the y coordinates
                    //min.Y = CanvasManager.CurrentCanvas.ImageSize.Y - max.Y;

                    int activeLayer = CanvasManager.CurrentCanvas.LayerManager.ActiveLayer;
                    System.Drawing.Color color = CanvasManager.CurrentCanvas.LayerManager.Layers[activeLayer].OutputTexture.GetPixel((int)point.X, (int)point.Y);
                    System.Windows.Media.Color c2 = Color.FromArgb(color.R, color.G, color.B, color.A);

                    colorManager.addColor(c2);

                    SolidColorBrush scb = new SolidColorBrush(c2);
                    rectCurrColor.Fill = scb;
                    txtRGBR.Text = color.R.ToString();
                    txtRGBG.Text = color.G.ToString();
                    txtRGBB.Text = color.B.ToString();
                    txtRGBA.Text = color.A.ToString();
                    txtHex.Text = "#" + colorManager.colorToHexString(c2);

                    savedColors.Items.Refresh();
                }
                else if (ToolManager.ActiveTool != null)
                {
                    if (CanvasManager.CurrentCanvas != null)
                    {
                        System.Drawing.PointF p = new System.Drawing.Point(e.X, e.Y);
                        //p.X /= (float)500.0;
                        //p.Y /= (float)wfhCanvasHost.Height;
                        System.Windows.Media.Color color = new Color();
                        color = colorManager.getForeground();
                        //paintbrush.draw(wfhCanvasHost.Child as GRControl, p, color);
                        pastPositions.Clear();
                        pastPositions.Add(p);
                        pastPositions.Add(p);
                        ToolManager.ActiveTool.draw(wfhCanvasHost.Child as GRControl, p, pastPositions, color, 1.0f);
                    }
                }
                else if (selectionState == SelectionState.Rectangle || selectionState == SelectionState.Ellipse)
                {
                    firstSelect = false;
                    firstSelectionPoint = new System.Drawing.Point(e.X, (int)wfhCanvasHost.Height - e.Y);
                }

            }

            wfhCanvasHost.Child.Refresh();
        }

        void Child_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                if (ToolManager.ActiveTool != null)
                {
                    if (CanvasManager.CurrentCanvas != null)
                    {
                        if (ToolManager.ActiveTool.getApplying())
                        {
                           
                            int activeCanvas = CanvasManager.getCurrentCanvas();
                            int activeLayer = CanvasManager.getCanvas(activeCanvas).LayerManager.ActiveLayer;
                            int width = CanvasManager.getCanvas(activeCanvas).LayerManager.Layers[activeLayer].BaseTexture.Width;
                            int height = CanvasManager.getCanvas(activeCanvas).LayerManager.Layers[activeLayer].BaseTexture.Height;

                            //update the state manager
                            /*CanvasManager.getCanvas(activeCanvas).StateManager.addState(
                                CanvasManager.getCanvas(activeCanvas).LayerManager.Layers[activeLayer],
                                ToolManager.ActiveTool.getName());*/

                            lbHistory.ItemsSource = CanvasManager.getCanvas(activeCanvas).StateManager.getStates;
                            lbHistory.Items.Refresh();
                           

                            //apply the tool's changes to the active texture
                            CanvasManager.getCanvas(activeCanvas).LayerManager.Layers[activeLayer].grBaseTexture.SetAsActiveTexture(CanvasManager.gr);
                            
                            CanvasManager.getCanvas(activeCanvas).LayerManager.Layers[activeLayer]
                                    .grBaseTexture.TransferOpenGLTextureDataBackToHostMemoryAndCopyToCompatibleBitmap(
                                        CanvasManager.gr,
                                        CanvasManager.getCanvas(activeCanvas).LayerManager.Layers[activeLayer].BaseTexture);

                            ToolManager.ActiveTool.setApplying(false);

                            CanvasManager.getCanvas(activeCanvas).StateManager.addState(
                                CanvasManager.getCanvas(activeCanvas).LayerManager.Layers[activeLayer],
                                ToolManager.ActiveTool.getName());
                        }
                    }
                }
                else if (selectionState == SelectionState.Rectangle || selectionState == SelectionState.Ellipse)
                {
                    if (dragging)
                    {
                        firstSelect = true;
                        //set min and max properly reguardless of positions clicked
                        System.Drawing.Point finalPoint = new System.Drawing.Point(e.X, (int)Height - e.Y);
                        int temp;
                        if (firstSelectionPoint.X > finalPoint.X)
                        {
                            temp = firstSelectionPoint.X;
                            firstSelectionPoint.X = finalPoint.X;
                            finalPoint.X = temp;
                        }
                        if (firstSelectionPoint.Y > finalPoint.Y)
                        {
                            temp = firstSelectionPoint.Y;
                            firstSelectionPoint.Y = finalPoint.Y;
                            finalPoint.Y = temp;
                        }

                        if (selectionState == SelectionState.Rectangle)
                            CanvasManager.CurrentCanvas.selection.selectBox(firstSelectionPoint, finalPoint, new System.Drawing.PointF((float)wfhCanvasHost.ActualWidth, (float)wfhCanvasHost.ActualHeight));
                        else if (selectionState == SelectionState.Ellipse)
                            CanvasManager.CurrentCanvas.selection.selectEllipse(firstSelectionPoint, finalPoint, new System.Drawing.PointF((float)wfhCanvasHost.ActualWidth, (float)wfhCanvasHost.ActualHeight));
                    }
                    else if (selectionState != SelectionState.None)
                        CanvasManager.CurrentCanvas.selection.clearSelection();
                }
                
            }
            dragging = false;
            pastPositions.Clear();
        }

        void gr_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
        {
            if (CanvasManager.CurrentCanvas != null)
                CanvasManager.CurrentCanvas.Draw(sender as GRControl);
        }    
        #endregion     
        
        #region Status Bar Methods
        /// <summary>
        /// Returns the mouse position in the window.
        /// </summary>
        /// <param name="mouseEv"></param>
        //TODO: This has to be updated to return the mouse position within the opengl window, once that is developed.
        protected override void OnMouseMove(MouseEventArgs mouseEv)
        {
            MousePosText.Text = this.PointToScreen(Mouse.GetPosition(this)).ToString();
            POINTAPI point;
            GetCursorPos(out point);
            Point pos = new Point(point.X, point.Y);
            mouseColor.Text = GetPixelColor(pos).ToString();

            wfhCanvasHost.Child.Refresh();           
        }

        protected void OnCanvasMouseDown(MouseEventArgs mouseEv)
        {

        } 
        #endregion

        
        

        #region Menu Item Click Methods
        protected void New_Click(object sender, RoutedEventArgs e)
        {
            //"New" clicked - create window to get info
            newDocument(); 
        }
       
        void docNameTextBox_LostFocus(object sender, RoutedEventArgs e)
        {
            documentName = ((TextBox)sender).Text;
        }
        void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            //I don't know of any other way to do this
            Application.Current.Windows[1].Close();
        }

        void btnOkay_Click(object sender, RoutedEventArgs e)
        {

            Application.Current.Windows[1].Close();

            FileManager.newProject(documentName, previewX, previewY);
            wfhCanvasHost.Width = previewX;
            wfhCanvasHost.Height = previewY;

            ToolManager.ReloadShaders();
            TabbedDocuments.TabRowTabControl.Items.Refresh();
            TabbedDocuments.TabRowTabControl.SelectedIndex = (CanvasManager.Canvases.Count - 1);
            
        }

        void docWidthTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            try
            {
                previewX = Int32.Parse(((TextBox)sender).Text);
                drawPreview();
            }
            catch (Exception ex)
            {
               
                
            }
        }

        void docHeightTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            try
            {
                previewY = Int32.Parse(((TextBox)sender).Text);
                drawPreview();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        protected void drawPreview()
        {
            int tempX = previewX;
            int tempY = previewY;

            if (tempX > 150)
            {
                while (tempX > 150)
                {
                    tempX = tempX / 2;
                    tempY = tempY / 2;
                }

            }
            if (tempY > 150)
            {
                while (tempY > 150)
                {
                    tempX = tempX / 2;
                    tempY = tempY / 2;
                }

            }
            previewSnap.Width = tempX;
            previewSnap.Height = tempY;
            previewSnap.Fill = Brushes.White;
        }
        /// <summary>
        /// Exit Click Method
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Exit_Click(object sender, RoutedEventArgs e)
        {
            //close the window
            this.Close();
        }
        
        
        /// <summary>
        /// Open Click Method
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        //TODO: Set default document to open based on whatever default extension we develop for our app.
        private void Open_Click(object sender, RoutedEventArgs e)
        {
            //uses open dialog
            Microsoft.Win32.OpenFileDialog openDialog = new Microsoft.Win32.OpenFileDialog();
            openDialog.ShowDialog();

            FileManager.load(openDialog.FileName);

            if (CanvasManager.Canvases.Count > 0)
            {
                lbLayers.ItemsSource = CanvasManager.CurrentCanvas.LayerManager.Layers;
                lbLayers.Items.Refresh();
                ToolManager.ReloadShaders();
            }
            TabbedDocuments.TabRowTabControl.Items.Refresh();
            TabbedDocuments.TabRowTabControl.SelectedIndex = (CanvasManager.Canvases.Count - 1);

            
          
        }
        /// <summary>
        /// Save Click Method
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        //TODO: Set default document to open based on whatever default extension we develop for our app.
        private void Save_Click(object sender, RoutedEventArgs e)
        {
            //uses open dialog
            Microsoft.Win32.SaveFileDialog saveDialog = new Microsoft.Win32.SaveFileDialog();
            saveDialog.Filter = "IMP Project (*.imp)|*.imp|JPEG (*.jpeg)|.jpeg|GIF (*.gif)|.gif|PNG (*.png)|.png|Bitmap (*.bmp)|*.bmp|All Files (*.*)|*.*";
            saveDialog.ShowDialog();

            FileManager.save(saveDialog.FileName, (long)100);
        }
        private void Close_Click(object sender, RoutedEventArgs e)
        {
            //right now just close the tab, eventually will have to check to see if saved/updated since last save/etc.
            CanvasManager.removeCanvas(TabbedDocuments.TabRowTabControl.SelectedIndex);
            TabbedDocuments.TabRowTabControl.Items.Refresh();
            
        }

        private void About_Click(object sender, RoutedEventArgs e)
        {
            Window aboutWindow = new Window();
            aboutWindow.Owner = App.Current.MainWindow;
            aboutWindow.VerticalAlignment = VerticalAlignment.Center;
            aboutWindow.HorizontalAlignment = HorizontalAlignment.Center;
            aboutWindow.Width = 300;
            aboutWindow.Height = 150;
            aboutWindow.Show();
            
        }
        private void Print_Click(object sender, RoutedEventArgs e)
        {
            PrintDialog printDlg = new System.Windows.Controls.PrintDialog();

            if (printDlg.ShowDialog() == true)
            {
                printDlg.PrintVisual(this, documentName);
            }
        }        
        #endregion

        #region New Document Method
        protected void newDocument()
        {
            ResourceDictionary dict = new ResourceDictionary();
            dict.Source = new Uri("Resources/shared.xaml", UriKind.Relative);

            System.Windows.Media.Brush sb = (System.Windows.Media.Brush)this.FindResource("DarkGradReverse");

            Grid newDocGrid = new Grid()
            {
                Name = "newMainGrid",
                //ShowGridLines = true,                
                Background = sb

            };

            ColumnDefinition column0 = new ColumnDefinition();
            column0.Width = new GridLength(100);
            ColumnDefinition column1 = new ColumnDefinition();
            column1.Width = new GridLength(150);
            ColumnDefinition column2 = new ColumnDefinition();
            column2.Width = new GridLength(250);

            newDocGrid.ColumnDefinitions.Add(column0);
            newDocGrid.ColumnDefinitions.Add(column1);
            newDocGrid.ColumnDefinitions.Add(column2);

            RowDefinition row0 = new RowDefinition();
            row0.Height = new GridLength(50);
            RowDefinition row1 = new RowDefinition();
            row1.Height = new GridLength(30);
            RowDefinition row2 = new RowDefinition();
            row2.Height = new GridLength(30);
            RowDefinition row3 = new RowDefinition();
            row3.Height = new GridLength(30);
            RowDefinition row4 = new RowDefinition();
            row4.Height = new GridLength(30);
            RowDefinition row5 = new RowDefinition();
            row5.Height = new GridLength(30);
            RowDefinition row6 = new RowDefinition();
            row5.Height = new GridLength(30);

            newDocGrid.RowDefinitions.Add(row0);
            newDocGrid.RowDefinitions.Add(row1);
            newDocGrid.RowDefinitions.Add(row2);
            newDocGrid.RowDefinitions.Add(row3);
            newDocGrid.RowDefinitions.Add(row4);
            newDocGrid.RowDefinitions.Add(row5);
            newDocGrid.RowDefinitions.Add(row6);

            //define default color - pita 
            BrushConverter bc = new BrushConverter();
            System.Windows.Media.Brush fontColor;
            fontColor = (System.Windows.Media.Brush)bc.ConvertFrom("#80FFFFFF");

            TextBlock docName = new TextBlock()
            {
                HorizontalAlignment = HorizontalAlignment.Right,
                VerticalAlignment = VerticalAlignment.Bottom,
                Text = "Name: ",
                Foreground = fontColor,
                Margin = new Thickness(0, 0, 0, 5)

            };
            TextBox docNameTextBox = new TextBox() { Height = 16, Width = 140, HorizontalAlignment = HorizontalAlignment.Left, Margin = new Thickness(5, 0, 0, 5), VerticalAlignment = VerticalAlignment.Bottom };
            TextBox docWidthTextBox = new TextBox() { Height = 16, Width = 65, HorizontalAlignment = HorizontalAlignment.Left, Margin = new Thickness(5, 0, 0, 5), VerticalAlignment = VerticalAlignment.Bottom };
            TextBox docHeightTextBox = new TextBox() { Height = 16, Width = 65, HorizontalAlignment = HorizontalAlignment.Left, Margin = new Thickness(5, 0, 0, 5), VerticalAlignment = VerticalAlignment.Bottom };
            TextBox docResolutionTextBox = new TextBox() { Text = "72", Height = 16, Width = 50, HorizontalAlignment = HorizontalAlignment.Left, Margin = new Thickness(5, 0, 0, 5), VerticalAlignment = VerticalAlignment.Bottom };

            docNameTextBox.LostFocus += new RoutedEventHandler(docNameTextBox_LostFocus);

            docWidthTextBox.TextChanged += new TextChangedEventHandler(docWidthTextBox_TextChanged);
            docHeightTextBox.TextChanged += new TextChangedEventHandler(docHeightTextBox_TextChanged);
            TextBlock docWidth = new TextBlock()
            {
                HorizontalAlignment = HorizontalAlignment.Right,
                VerticalAlignment = VerticalAlignment.Bottom,
                Text = "Width: ",
                Foreground = fontColor,
                Margin = new Thickness(0, 0, 0, 5)

            };
            TextBlock docHeight = new TextBlock()
            {
                HorizontalAlignment = HorizontalAlignment.Right,
                VerticalAlignment = VerticalAlignment.Bottom,
                Text = "Height: ",
                Foreground = fontColor,
                Margin = new Thickness(0, 0, 0, 5)

            };
            TextBlock docResolution = new TextBlock()
            {
                HorizontalAlignment = HorizontalAlignment.Right,
                VerticalAlignment = VerticalAlignment.Bottom,
                Text = "Resolution: ",
                Foreground = fontColor,
                Margin = new Thickness(0, 0, 0, 5)

            };
            TextBlock docMode = new TextBlock()
            {
                HorizontalAlignment = HorizontalAlignment.Right,
                VerticalAlignment = VerticalAlignment.Bottom,
                Text = "Color Mode: ",
                Foreground = fontColor,
                Margin = new Thickness(0, 0, 0, 5)

            };
            TextBlock docBackground = new TextBlock()
            {
                HorizontalAlignment = HorizontalAlignment.Right,
                VerticalAlignment = VerticalAlignment.Bottom,
                Text = "Background Fill: ",
                Foreground = fontColor,
                Margin = new Thickness(0, 0, 0, 5)

            };
            TextBlock docPreview = new TextBlock()
            {
                HorizontalAlignment = HorizontalAlignment.Left,
                VerticalAlignment = VerticalAlignment.Bottom,
                Text = "Preview (Scaled):",
                Foreground = fontColor,
                Margin = new Thickness(5, 0, 0, 5)

            };

            //TODO: move all this shit to XML docs and databind to cb's
            ComboBoxItem cbPixels = new ComboBoxItem() { Content = "pixels" };
            ComboBoxItem cbInches = new ComboBoxItem() { Content = "inches" };
            ComboBoxItem cbCm = new ComboBoxItem() { Content = "cm" };
            ComboBoxItem cbMm = new ComboBoxItem() { Content = "mm" };

            ComboBoxItem cbPixelsInch = new ComboBoxItem() { Content = "pixels/inch" };
            ComboBoxItem cbCmInch = new ComboBoxItem() { Content = "pixels/cm" };

            ComboBoxItem cbBitmap = new ComboBoxItem() { Content = "Bitmap" };
            ComboBoxItem cbGrayscale = new ComboBoxItem() { Content = "Grayscale" };
            ComboBoxItem cbRGB = new ComboBoxItem() { Content = "RGB" };

            ComboBoxItem cb1 = new ComboBoxItem() { Content = "1 bit" };
            ComboBoxItem cb8 = new ComboBoxItem() { Content = "8 bit" };
            ComboBoxItem cb16 = new ComboBoxItem() { Content = "16 bit" };
            ComboBoxItem cb32 = new ComboBoxItem() { Content = "32 bit" };

            ComboBoxItem cbTrans = new ComboBoxItem() { Content = "Transparent" };
            ComboBoxItem cbWhite = new ComboBoxItem() { Content = "White" };
            ComboBoxItem cbBackground = new ComboBoxItem() { Content = "Background Color" };

            List<ComboBoxItem> cbList = new List<ComboBoxItem>();
            List<ComboBoxItem> cbListRes = new List<ComboBoxItem>();
            List<ComboBoxItem> cbListColor1 = new List<ComboBoxItem>();
            List<ComboBoxItem> cbListColor2 = new List<ComboBoxItem>();
            List<ComboBoxItem> cbListBackgroundColor = new List<ComboBoxItem>();

            cbListBackgroundColor.Add(cbTrans);
            cbListBackgroundColor.Add(cbWhite);
            cbListBackgroundColor.Add(cbBackground);

            cbListColor1.Add(cbBitmap);
            cbListColor1.Add(cbGrayscale);
            cbListColor1.Add(cbRGB);

            cbListColor2.Add(cb1);
            cbListColor2.Add(cb8);
            cbListColor2.Add(cb16);
            cbListColor2.Add(cb32);

            cbListRes.Add(cbPixelsInch);
            cbListRes.Add(cbCmInch);

            cbList.Add(cbPixels);
            cbList.Add(cbInches);
            cbList.Add(cbCm);
            cbList.Add(cbMm);

            //not sure why it's bugging out with the itemssource, so duplicate the list
            //TODO: that didn't help, will fix it later
            List<ComboBoxItem> cbList2 = cbList;

            ComboBox docWidthCB = new ComboBox() { ItemsSource = cbList, SelectedIndex = 0, Height = 16, Width = 70, HorizontalAlignment = HorizontalAlignment.Right, Margin = new Thickness(0, 1, 5, 0) };
            ComboBox docHeightCB = new ComboBox() { ItemsSource = cbList2, SelectedIndex = 0, Height = 16, Width = 70, HorizontalAlignment = HorizontalAlignment.Right, Margin = new Thickness(0, 1, 5, 0) };
            ComboBox docResCB = new ComboBox() { ItemsSource = cbListRes, SelectedIndex = 0, Height = 16, Width = 85, HorizontalAlignment = HorizontalAlignment.Right, Margin = new Thickness(0, 1, 5, 0) };
            ComboBox docBackgroundCB = new ComboBox() { ItemsSource = cbListBackgroundColor, SelectedIndex = 0, Height = 16, Width = 140, HorizontalAlignment = HorizontalAlignment.Left, Margin = new Thickness(5, 1, 5, 0) };
            ComboBox docColor1CB = new ComboBox() { ItemsSource = cbListColor1, SelectedIndex = 2, Height = 16, Width = 78, HorizontalAlignment = HorizontalAlignment.Left, Margin = new Thickness(5, 1, 5, 0) };
            ComboBox docColor2CB = new ComboBox() { ItemsSource = cbListColor2, SelectedIndex = 1, Height = 16, Width = 57, HorizontalAlignment = HorizontalAlignment.Right, Margin = new Thickness(0, 1, 5, 0) };

            Button btnOkay = new Button { Content = "OK", HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Top, Height = 20, Width = 50, Margin = new Thickness(20, 10, 0, 0) };
            Button btnCancel = new Button { Content = "Cancel", HorizontalAlignment = HorizontalAlignment.Right, VerticalAlignment = VerticalAlignment.Top, Height = 20, Width = 70, Margin = new Thickness(0, 10, 5, 0) };
            btnOkay.Click += new RoutedEventHandler(btnOkay_Click);
            btnCancel.Click += new RoutedEventHandler(btnCancel_Click);

            newDocGrid.Children.Add(docName);
            newDocGrid.Children.Add(docNameTextBox);
            newDocGrid.Children.Add(docWidth);
            newDocGrid.Children.Add(docHeight);
            newDocGrid.Children.Add(docResolution);
            newDocGrid.Children.Add(docMode);
            newDocGrid.Children.Add(docBackground);
            newDocGrid.Children.Add(docWidthTextBox);
            newDocGrid.Children.Add(docHeightTextBox);
            newDocGrid.Children.Add(docWidthCB);
            newDocGrid.Children.Add(docHeightCB);
            newDocGrid.Children.Add(docResCB);
            newDocGrid.Children.Add(docColor1CB);
            newDocGrid.Children.Add(docColor2CB);
            newDocGrid.Children.Add(docResolutionTextBox);
            newDocGrid.Children.Add(docBackgroundCB);
            newDocGrid.Children.Add(previewSnap);
            newDocGrid.Children.Add(docPreview);
            newDocGrid.Children.Add(btnOkay);
            newDocGrid.Children.Add(btnCancel);


            Grid.SetColumn(docName, 0);
            Grid.SetRow(docName, 0);
            Grid.SetColumn(docNameTextBox, 1);
            Grid.SetRow(docNameTextBox, 0);
            Grid.SetColumn(docWidthTextBox, 1);
            Grid.SetRow(docWidthTextBox, 1);
            Grid.SetColumn(docWidthCB, 1);
            Grid.SetRow(docWidthCB, 1);
            Grid.SetColumn(docHeightTextBox, 1);
            Grid.SetRow(docHeightTextBox, 2);
            Grid.SetColumn(docHeightCB, 1);
            Grid.SetRow(docHeightCB, 2);
            Grid.SetColumn(docWidth, 0);
            Grid.SetRow(docWidth, 1);
            Grid.SetColumn(docHeight, 0);
            Grid.SetRow(docHeight, 2);
            Grid.SetColumn(docResolution, 0);
            Grid.SetRow(docResolution, 3);
            Grid.SetColumn(docResolutionTextBox, 1);
            Grid.SetRow(docResolutionTextBox, 3);
            Grid.SetColumn(docResCB, 1);
            Grid.SetRow(docResCB, 3);
            Grid.SetColumn(docMode, 0);
            Grid.SetRow(docMode, 4);
            Grid.SetColumn(docColor1CB, 1);
            Grid.SetRow(docColor1CB, 4);
            Grid.SetColumn(docColor2CB, 1);
            Grid.SetRow(docColor2CB, 4);
            Grid.SetColumn(docBackground, 0);
            Grid.SetRow(docBackground, 5);
            Grid.SetColumn(docBackgroundCB, 1);
            Grid.SetRow(docBackgroundCB, 5);
            Grid.SetColumn(previewSnap, 2);
            Grid.SetRow(previewSnap, 1);
            Grid.SetRowSpan(previewSnap, 5);
            Grid.SetColumn(docPreview, 2);
            Grid.SetRow(docPreview, 0);
            Grid.SetColumn(btnOkay, 1);
            Grid.SetRow(btnOkay, 6);
            Grid.SetColumn(btnCancel, 1);
            Grid.SetRow(btnCancel, 6);

            Window newDocWindow = new Window()
            {
                Content = newDocGrid,
                Width = 500,
                Height = 350,
                Name = "newDocWindow",
                Owner = this,
                Title = "New",
                ResizeMode = ResizeMode.NoResize

            };

            newDocWindow.ShowDialog();
            newDocGrid.Children.Remove(previewSnap);
        } 
        #endregion

        private void Expander_Expanded(object sender, RoutedEventArgs e)
        {

        }

        private void btnPickColor_Click(object sender, RoutedEventArgs e)
        {
            colorPickerActive = true;
        }       

        private void Rectangle_MouseDown(object sender, MouseButtonEventArgs e)
        {
            POINTAPI point;
            GetCursorPos(out point);
            Point pos = new Point(point.X, point.Y);
            
            rectForegroundColor.Fill = GetPixelColor(pos);
            Color newColor = (rectForegroundColor.Fill as SolidColorBrush).Color;
            colorManager.setForeground(newColor);
            
        }

        private void Grid_MouseEnter(object sender, MouseEventArgs e)
        {
            Cursor = Cursors.Hand;
        }

        private void Grid_MouseLeave(object sender, MouseEventArgs e)
        {
            Cursor = Cursors.Arrow;
        }

        private void txtRGBR_TextChanged(object sender, TextChangedEventArgs e)
        {
            if(isValidRGB())
            {
                updateCurrentColor();
            }
        }

        private void txtRGBG_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (isValidRGB())
            {
                updateCurrentColor();
            }
        }

        private void txtRGBB_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (isValidRGB())
            {
                updateCurrentColor();
            }
        }

        private void txtHSLH_TextChanged(object sender, TextChangedEventArgs e)
        {

        }

        private void txtHSLS_TextChanged(object sender, TextChangedEventArgs e)
        {

        }

        private void txtHSLL_TextChanged(object sender, TextChangedEventArgs e)
        {

        }

        private void txtHex_TextChanged(object sender, TextChangedEventArgs e)
        {

        }

        protected void updateCurrentColor()
        {
            Color newColor = new Color();

            try
            {
                newColor.R = byte.Parse(txtRGBR.Text.Trim());
                newColor.G = byte.Parse(txtRGBG.Text.Trim());
                newColor.B = byte.Parse(txtRGBB.Text.Trim());
                newColor.A = byte.Parse("255");
           }
            catch (Exception ex)
            {

            }

            //colorManager.addColor(newColor);            
            
            SolidColorBrush scb = new SolidColorBrush(newColor);
            rectCurrColor.Fill = scb;
            txtHex.Text = "#" + colorManager.colorToHexString(newColor);

            colorManager.setMixer(newColor);
            
        }
        protected bool isValidRGB()
        {
            if (txtRGBR.Text == String.Empty || txtRGBG.Text == String.Empty || txtRGBB.Text == String.Empty)
            {
                return false;
            }
            else
            {
                if (Convert.ToInt32(txtRGBR.Text) <= 255 || Convert.ToInt32(txtRGBG.Text) <= 255 || Convert.ToInt32(txtRGBB.Text) <= 255)
                {
                    return true;
                }
            }
            return false;
        }

        private void Grid_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            POINTAPI point;
            GetCursorPos(out point);
            Point pos = new Point(point.X, point.Y);

            rectBackgroundColor.Fill = GetPixelColor(pos);
            Color newColor = (rectForegroundColor.Fill as SolidColorBrush).Color;
            colorManager.setBackground(newColor);
        }

        private void rectCurrColor_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            rectForegroundColor.Fill = rectCurrColor.Fill;
            colorManager.setForeground((rectForegroundColor.Fill as SolidColorBrush).Color);
        }

        private void rectCurrColor_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            rectBackgroundColor.Fill = rectCurrColor.Fill;
            colorManager.setForeground((rectBackgroundColor.Fill as SolidColorBrush).Color);
        }

        private void cbSteps_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
                    
        }

        private void btnBlend_Click(object sender, RoutedEventArgs e)
        {
            if (colorManager.getBlendColor1() != null && colorManager.getBlendColor2() != null)
            {
                blendedColors.ItemsSource = colorManager.generateColors(colorManager.getBlendColor1(), colorManager.getBlendColor2(), Convert.ToInt32(cbSteps.SelectedItem));  
            }
            
        }

        private void btnAddBlend_Click(object sender, RoutedEventArgs e)
        {
            if (numBlends==0 || numBlends % 2 == 0)
            {
                colorManager.setBlendColor1((rectCurrColor.Fill as SolidColorBrush).Color);
                rectBlendColor1.Fill = new SolidColorBrush(colorManager.getBlendColor1());
                
            }
            else
            {
                colorManager.setBlendColor2((rectCurrColor.Fill as SolidColorBrush).Color);
                rectBlendColor2.Fill = new SolidColorBrush(colorManager.getBlendColor2());
            }            
            numBlends++;
        }

        private void btnNewLayer_Click(object sender, RoutedEventArgs e)
        {
            //add the layer stuff here
            //creates a blank layer
            CanvasManager.CurrentCanvas.LayerManager.addTransparentLayer(
                CanvasManager.CurrentCanvas.LayerManager.Layers[0].BaseTexture.Width,
                CanvasManager.CurrentCanvas.LayerManager.Layers[0].BaseTexture.Height);
            lbLayers.Items.Refresh();
        }

        private void btnRemoveLayer_Click(object sender, RoutedEventArgs e)
        {
            //remove the current layer
            CanvasManager.CurrentCanvas.LayerManager.deleteLayer(
                CanvasManager.CurrentCanvas.LayerManager.Layers[CanvasManager.CurrentCanvas.LayerManager.ActiveLayer].ID);
            lbLayers.Items.Refresh();
        }

        private void expanderCol_Expanded(object sender, RoutedEventArgs e)
        {
            expanderLay.IsExpanded = false;
            expanderHist.IsExpanded = false;
            expanderTools.IsExpanded = false;
            expanderMod.IsExpanded = false;

        }
        private void expanderMod_Expanded(object sender, RoutedEventArgs e)
        {
            expanderLay.IsExpanded = false;
            expanderHist.IsExpanded = false;
            expanderTools.IsExpanded = false;
            expanderCol.IsExpanded = false;
        }

        private void expanderLay_Expanded(object sender, RoutedEventArgs e)
        {
            expanderHist.IsExpanded = false;
            expanderCol.IsExpanded = false;
            expanderTools.IsExpanded = false;
            expanderMod.IsExpanded = false;
        }

        private void expanderHist_Expanded(object sender, RoutedEventArgs e)
        {
            expanderCol.IsExpanded = false;
            expanderLay.IsExpanded = false;
            expanderTools.IsExpanded = false;
            expanderMod.IsExpanded = false;

        }



        private void ToolButton_Click(object sender, RoutedEventArgs e)
        {
            selectionState = SelectionState.None;
            ToolManager.SetTool((ToolType)(-1));

            colorManager.addColor(colorManager.getMixer());
            savedColors.Items.Refresh();
            switch (((Button)sender).Name)
            {
                case "selectLasso":
                    selectionState = SelectionState.Lasso;
                    gridEraser.Visibility = Visibility.Collapsed;
                    gridPaintBrush.Visibility = Visibility.Collapsed;
                    gridSelection.Visibility = Visibility.Visible;
                    break;
                case "selectRectangle":
                    selectionState = SelectionState.Rectangle;
                    gridEraser.Visibility = Visibility.Collapsed;
                    gridPaintBrush.Visibility = Visibility.Collapsed;
                    gridSelection.Visibility = Visibility.Visible;
                    break;
                case "selectEllipse":
                    selectionState = SelectionState.Ellipse;
                    gridEraser.Visibility = Visibility.Collapsed;
                    gridPaintBrush.Visibility = Visibility.Collapsed;
                    gridSelection.Visibility = Visibility.Visible;
                    break;
                case "selectArea":
                    selectionState = SelectionState.Area;
                    gridEraser.Visibility = Visibility.Collapsed;
                    gridPaintBrush.Visibility = Visibility.Collapsed;
                    gridSelection.Visibility = Visibility.Visible;
                    break;
                case "paintbucket":
                    ToolManager.SetTool(ToolType.Paintbucket);
                    gridEraser.Visibility = Visibility.Collapsed;
                    gridPaintBrush.Visibility = Visibility.Collapsed;
                    gridSelection.Visibility = Visibility.Collapsed;
                    break;
                case "gradient":
                    //ToolManager.SetTool(ToolType.Gradient);
                    ToolManager.SetTool(ToolType.Blur);
                    gridEraser.Visibility = Visibility.Collapsed;
                    gridPaintBrush.Visibility = Visibility.Collapsed;
                    gridSelection.Visibility = Visibility.Collapsed;
                    break;
                case "brush":
                    ToolManager.SetTool(ToolType.Brush);
                    gridEraser.Visibility = Visibility.Collapsed;
                    gridPaintBrush.Visibility = Visibility.Visible;
                    gridSelection.Visibility = Visibility.Collapsed;
                    break;
                case "eraser":
                    ToolManager.SetTool(ToolType.Eraser);
                    gridPaintBrush.Visibility = Visibility.Collapsed;
                    gridEraser.Visibility = Visibility.Visible;
                    gridSelection.Visibility = Visibility.Collapsed;
                    break;
                case "text":
                    ToolManager.SetTool(ToolType.Text);
                    gridEraser.Visibility = Visibility.Collapsed;
                    gridPaintBrush.Visibility = Visibility.Collapsed;
                    gridSelection.Visibility = Visibility.Collapsed;
                    break;
                case "zoom":
                    ToolManager.SetTool(ToolType.Zoom);
                    break;
            };
        }

        private void menuUndo_Click(object sender, RoutedEventArgs e)
        {
            int activeCanvas = CanvasManager.getCurrentCanvas();
            int activeLayer = CanvasManager.getCanvas(activeCanvas).LayerManager.ActiveLayer;

            //save the present state

            /*if (CanvasManager.getCanvas(activeCanvas).StateManager.isHead() 
                && !CanvasManager.getCanvas(activeCanvas).StateManager.getStates[CanvasManager.getCanvas(activeCanvas).StateManager.getStates.Count - 1].getName().Contains("Undo"))
            {
                CanvasManager.getCanvas(activeCanvas).StateManager.addState(
                    CanvasManager.getCanvas(activeCanvas).LayerManager.Layers[activeLayer],
                    "Undo " + ToolManager.ActiveTool.getName());
            }*/

            CanvasManager.CurrentCanvas.StateManager.undo();

            lbHistory.Items.Refresh();
        }

        private void menuRedo_Click(object sender, RoutedEventArgs e)
        {
            CanvasManager.CurrentCanvas.StateManager.redo();
        }
        private void expanderTools_Expanded(object sender, RoutedEventArgs e)
        {

        }

        private void sliderSize_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            txtSize.Text = sliderSize.Value.ToString();
            ToolManager.ActiveTool.size = (float)sliderSize.Value;
        }

        private void sliderHardness_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            txtHardness.Text = sliderHardness.Value.ToString();
            ToolManager.ActiveTool.hardness = (float)sliderHardness.Value;
        }

        private void sliderScatter_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            txtScatter.Text = sliderScatter.Value.ToString();
            ToolManager.ActiveTool.scatter = (float)sliderScatter.Value;
        }

        private void sliderSpacing_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            txtSpacing.Text = sliderSpacing.Value.ToString();
            ToolManager.ActiveTool.spacing = (float)sliderSpacing.Value;
        }

        private void sliderOpacity_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            txtOpacity.Text = sliderOpacity.Value.ToString();
            ToolManager.ActiveTool.opacity = (float)sliderOpacity.Value;
        }

        private void sliderPressure_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            txtPressure.Text = sliderPressure.Value.ToString();
        }

        private void sliderESize_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            txtESize.Text = sliderESize.Value.ToString();
        }

        private void sliderEOpacity_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            txtEOpacity.Text = sliderEOpacity.Value.ToString();
        }

        private void sliderEPressure_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            txtEPressure.Text = sliderEPressure.Value.ToString();
        }

        private void sliderEHardness_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            txtEHardness.Text = sliderEHardness.Value.ToString();
        }

        private void sliderEScatter_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            txtEScatter.Text = sliderEScatter.Value.ToString();
        }

        private void sliderESpacing_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            txtESpacing.Text = sliderESpacing.Value.ToString();
        }

        private void sliderFeather_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            txtFeather.Text = sliderFeather.Value.ToString();
        }

        private void lbLayers_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            lbModifiers.ItemsSource = CanvasManager.CurrentCanvas.LayerManager.Layers[lbLayers.SelectedIndex].ModifierList;
            lbModifiers.Items.Refresh();
            CanvasManager.CurrentCanvas.LayerManager.ActiveLayer = lbLayers.SelectedIndex;

        }

        private void btnApplyMod_Click(object sender, RoutedEventArgs e)
        {
            if (CanvasManager.CurrentCanvas != null)
            {
                if (cbModifiers.SelectedIndex == 0)
                {
                    //edge detect
                    CanvasManager.CurrentCanvas.LayerManager.Layers[CanvasManager.CurrentCanvas.LayerManager.ActiveLayer].ModifierList.Add(new EdgeDetect());
                }
                else if (cbModifiers.SelectedIndex == 1)
                {
                    //gaussian blur
                    CanvasManager.CurrentCanvas.LayerManager.Layers[CanvasManager.CurrentCanvas.LayerManager.ActiveLayer].ModifierList.Add(new GaussianBlur());
                }
                else if (cbModifiers.SelectedIndex == 2)
                {
                    //mirror plane
                    CanvasManager.CurrentCanvas.LayerManager.Layers[CanvasManager.CurrentCanvas.LayerManager.ActiveLayer].ModifierList.Add(new MirrorPlane());
                }
                else if (cbModifiers.SelectedIndex == 3)
                {
                    //normal map
                    CanvasManager.CurrentCanvas.LayerManager.Layers[CanvasManager.CurrentCanvas.LayerManager.ActiveLayer].ModifierList.Add(new NormalMap());
                }
                else if (cbModifiers.SelectedIndex == 4)
                {
                    //offset
                    CanvasManager.CurrentCanvas.LayerManager.Layers[CanvasManager.CurrentCanvas.LayerManager.ActiveLayer].ModifierList.Add(new Offset());
                }
            }
        }

        private void sliderGausAmount_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            txtGausAmount.Text = sliderGausAmount.Value.ToString();
        }
    }
}
